package com.sun.common.core.utils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

public class DateUtils {

    public static final Locale DEFAULT_LOCALE;
    public static final String FORMAT_DATE_DEFAULT = "yyyy-MM-dd";
    public static final String FORMAT_DATE_YYYYMMDD = "yyyyMMdd";
    public static final String FORMAT_DATE_YYYY_MM_DD = "yyyy-MM-dd";
    public static final String FORMAT_DATE_PATTERN_1 = "yyyy/MM/dd";
    public static final String FORMAT_DATE_PATTERN_2 = "yyyy/M/dd";
    public static final String FORMAT_DATE_PATTERN_3 = "yyyy/MM/d";
    public static final String FORMAT_DATE_PATTERN_4 = "yyyy/M/d";
    public static final String FORMAT_DATE_YYYY_MM_DD_HHMMSS = "yyyyMMddHHmmss";
    public static final String FORMAT_DATE_YYYY_MM_DD_HH_MM_SS =
            "yyyy-MM-dd HH:mm:ss";
    public static final String FORMAT_DATE_YYYY_MM_DD_HHMM = "yyyy-MM-dd HHmm";
    public static final String FORMAT_DATE_YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
    public static final String FORMAT_DATE_HH_MM = "HH:mm";
    public static final String FORMAT_DATE_HH_MM_SS = "HH:mm:ss";
    public static final String FORMAT_DATE_HHMM = "HHmm";
    public static final String FORMAT_DATE_HHMMSS = "HHmmss";
    public static final String FORMAT_DATE_YYMMDD = "yyMMdd";
    public static final String FORMAT_DATE_YYYY = "yyyy";
    public static final String FORMAT_WORK_TIME = "yyyy-MM-dd HHmmss";
    public static final String FORMAT_DATE_YYYY_MM_DDHHMMSS = "yyyy-MM-ddHHmmss";
    public static final String FORMAT_DATE_YYYYMMDD_BLANK_HHMMSS =
            "yyyyMMdd HH:mm:ss";

    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public DateUtils() {
    }


    public static final String getCurrentDateAsString(String formatPattern) {
        Date date = getCurrentDate();
        return format(date, formatPattern);
    }

    public static final Date getCurrentDate() {
        return Calendar.getInstance().getTime();
    }

    public static final String format(Date date) {
        if (date == null) {
            return "";
        } else {
            return format(date, "yyyy-MM-dd");
        }
    }

    public static final String formatDateTime(Date date) {
        if (date == null) {
            return "";
        } else {
            return format(date, "yyyy-MM-dd HH:mm:ss");
        }
    }

    public static final String format(Date date, String formatPattern) {
        if (date == null) {
            return "";
        } else {
            return (new SimpleDateFormat(formatPattern)).format(date);
        }
    }

    public static final Date parse(String stringValue) throws ParseException {
        return parseException(stringValue, "yyyy-MM-dd");
    }

    public static final Date parseException(String stringValue, String formatPattern)
            throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat(formatPattern);
        return format.parse(stringValue);
    }

    public static final Date parse(String stringValue, String formatPattern) {
        try {
            SimpleDateFormat format = new SimpleDateFormat(formatPattern);
            return format.parse(stringValue);
        } catch (ParseException e) {
            return null;
        }
    }

    public static final Date tryParse(String stringValue) throws ParseException {
        Date date = parse(stringValue, "yyyy-MM-dd");
        if (date != null) {
            return date;
        }
        date = parse(stringValue, "yyyyMMdd");
        if (date != null) {
            return date;
        }
        date = parse(stringValue, "yyyyMMddHHmmss");
        if (date != null) {
            return date;
        }
        date = parse(stringValue, "yyyy-MM-dd HH:mm:ss");
        if (date != null) {
            return date;
        }
        date = parse(stringValue, "yyyy-MM-dd HHmm");
        if (date != null) {
            return date;
        }
        date = parse(stringValue, "yyyy/MM/dd");
        if (date != null) {
            return date;
        }
        date = parse(stringValue, "yyyy/M/dd");
        if (date != null) {
            return date;
        }
        date = parse(stringValue, "yyyy/MM/d");
        if (date != null) {
            return date;
        }
        date = parse(stringValue, "yyyy/M/d");
        if (date != null) {
            return date;
        } else {
            return date;
        }
    }

    public static int getDayOfWeek(int SUN_FST_DAY_OF_WEEK) {
        if (SUN_FST_DAY_OF_WEEK > 7 || SUN_FST_DAY_OF_WEEK < 1) {
            return 0;
        }
        if (SUN_FST_DAY_OF_WEEK == 1) {
            return 7;
        } else {
            return SUN_FST_DAY_OF_WEEK - 1;
        }
    }

    public static Timestamp parseTimestamp(
            String stringValue,
            String formatPattern
    ) throws ParseException {
        return new Timestamp(parse(stringValue, formatPattern).getTime());
    }

    public static Timestamp parseTimestamp(Date d) {
        return new Timestamp(d.getTime());
    }

    public static Date addMilliseconds(Date date, int amount) {
        return add(date, 14, amount);
    }

    public static Date addMilliseconds(Date date, long amount) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        } else {
            Calendar c = Calendar.getInstance();
            c.setTimeInMillis(date.getTime() + amount);
            return c.getTime();
        }
    }

    public static Date addMinutes(Date date, int amount) {
        return add(date, 12, amount);
    }

    public static Date add(Date date, int calendarField, int amount) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        } else {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.add(calendarField, amount);
            return c.getTime();
        }
    }

    public static boolean isSameDay(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            throw new IllegalArgumentException("The date must not be null");
        } else {
            Calendar cal1 = Calendar.getInstance();
            cal1.setTime(date1);
            Calendar cal2 = Calendar.getInstance();
            cal2.setTime(date2);
            return isSameDay(cal1, cal2);
        }
    }

    public static boolean isSameDay(Calendar cal1, Calendar cal2) {
        if (cal1 == null || cal2 == null) {
            throw new IllegalArgumentException("The date must not be null");
        } else {
            return (
                    cal1.get(0) == cal2.get(0) &&
                            cal1.get(1) == cal2.get(1) &&
                            cal1.get(6) == cal2.get(6)
            );
        }
    }

    public static Date getFirstDayOfWeek(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(2);
        c.setTime(date);
        c.set(7, c.getFirstDayOfWeek());
        return c.getTime();
    }

    public static Date addWeekDayOfWeek(Date currentDate, int week) {
        Calendar c = new GregorianCalendar();
        c.setTime(currentDate);
        c.add(3, week);
        return c.getTime();
    }

    public static void main(String args1[]) throws ParseException {
    }

    public static String[] getMonthAndStartEndDays(String year, String weeks) {
        String res[] = new String[3];
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 08:00:00");
        SimpleDateFormat month = new SimpleDateFormat("MM");
        Calendar calendar = Calendar.getInstance();
        calendar.set(3, Integer.valueOf(weeks).intValue());
        calendar.set(1, Integer.valueOf(year).intValue());
        calendar.setFirstDayOfWeek(2);
        calendar.set(7, calendar.getFirstDayOfWeek());
        if ("1".equals(weeks) || "01".equals(weeks)) {
            res[0] = "01";
        } else {
            res[0] = month.format(calendar.getTime());
        }
        res[1] = sdf.format(calendar.getTime());
        calendar.add(7, 4);
        res[2] = sdf.format(calendar.getTime());
        return res;
    }

    public static Date formatToDay(Date date) {
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        String dayStr = f.format(date);

        try {
            return f.parse(dayStr);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取年份
     *
     * @param date
     * @return
     */
    public static Integer getYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(Calendar.YEAR);
        return year;
    }

    /**
     * 获取月份
     *
     * @param date
     * @return
     */
    public static Integer getMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int month = calendar.get(Calendar.MONTH) + 1;
        return month;
    }

    /**
     * 获取当前周次
     *
     * @param date
     * @return
     */
    public static Integer getWeekOfYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY); //将周一设为每周的第一天
        calendar.setTime(date);
        int week = calendar.get(Calendar.WEEK_OF_YEAR);
        int mouth = calendar.get(Calendar.MONTH);
        // JDK think 2015-12-31 as 2016 1th week
        //如果月份是12月，且求出来的周数是第一周，说明该日期实质上是这一年的第53周，也是下一年的第一周
        if (mouth >= 11 && week <= 1) {
            week += 52;
        }
        return week;
    }

    static {
        DEFAULT_LOCALE = Locale.CHINA;
    }
}
